White-throated sparrows are a common winter songbird throughout the southern United States. As the name suggests, they are easily recognizable by their white throats. Their song is an iconic whistle often described as “O Sweet Canada.” They can be found in woods, forest edges, shrubby fields, and at bird feeders. White-throated sparrows have tan striped and white striped color morphs which differ in behavior.
Emerald Hill is a popular daytime hangout for white-throated sparrows. Several individuals have been tagged with telemetry units to understand their movement patterns and habitat use. For this exercise, I will be looking at the home range of the individual 1E2D334C who I have nicknamed Nugget.
First, I will take a quick look at the spread of the data to check for any outliers.
qaqc_plot <- ggplot() + geom_point(data=nugget, aes(utm_easting,utm_northing), color = "orange2") +
labs(x="Easting", y="Northing") +
guides(color=guide_legend("Identifier"))
ggplotly(qaqc_plot)
Next, I will look at the home range of Nugget. For this analysis I am using minimum convex polygon to determine the minimum bounding geometry of the space used by Nugget.
## Data for a single individual
nugget_df <- as.data.frame(nugget)
xy <- c(as.data.frame(nugget_df$utm_easting),as.data.frame(nugget_df$utm_northing))
xy <- as.data.frame(xy)
## projecting the data to UTM
data.proj <- SpatialPointsDataFrame(xy,nugget_df, proj4string = CRS("+proj=utm +zone=16 +datum=WGS84 +units=m +no_defs"))
xy.sp <- SpatialPoints(data.proj@coords)
## MCP analysis
mcp.out <- mcp(xy.sp, percent=100, unout="ha")
## converting mcp to sf object for ggplot and points to df
mcp.sf <- st_as_sf(mcp.out)
mcp.points <- cbind((data.frame(xy)),nugget_df$individual.local.identifier)
colnames(mcp.points) <- c("x","y", "identifier")
# MCP plot
mcp.plot <- ggplot() + theme_bw() +
theme(axis.text.y = element_text(angle = 90, hjust = 0.5, vjust = 0.5)) +
theme(panel.grid = element_blank()) +
geom_spatial_rgb(data = emerald.hill, aes(x=x, y=y, r=red, g=green, b=blue)) +
geom_sf(data=mcp.sf, alpha = 0.3) +
geom_point(data=mcp.points, aes(x=x, y=y), color = "orange2") +
labs(x="Easting (m)", y="Northing (m)", title=mcp.points$identifier) +
theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5), panel.grid = element_blank())
mcp.plot + annotate("text", x = 467400, y = 4043640, label = paste(round(mcp.out@data$area,2),"ha"),
fontface = "bold", size = 5, color = "white")
It appears that Nugget uses a small portion of emerald hill about 10 ha
in size mostly in wooded areas. Some of Nugget’s range extends into the
mowed lawn of Emerald Hill and the residential neighborhood next
door.
Which areas does Nugget use more? Let’s look at Nugget’s frequency of use with kernel-density estimation. I used 95% KDE (blue), 75% KDE (green), and 50% KDE (yellow).
x <- as.data.frame(nugget_df$utm_easting)
y <- as.data.frame(nugget_df$utm_northing)
xy <- c(x,y)
## projecting the data to UTM
data.proj <- SpatialPointsDataFrame(xy,nugget_df, proj4string = CRS("+proj=utm +zone=16 +datum=WGS84 +units=m +no_defs"))
xy.sp <- SpatialPoints(data.proj@coords)
## KDE analysis at 95, 85, 75
kde<-kernelUD(xy.sp, h="href", kern="bivnorm", grid=100)
ver95 <- getverticeshr(kde, 95)
ver85 <- getverticeshr(kde, 85)
ver75 <- getverticeshr(kde, 75)
ver50 <- getverticeshr(kde, 50)
## converting to sf object and df
kde.points <- cbind((data.frame(data.proj@coords)),nugget_df$individual.local.identifier)
colnames(kde.points) <- c("x","y","identifier")
kde95.sf <- st_as_sf(ver95)
kde85.sf <- st_as_sf(ver85)
kde75.sf <- st_as_sf(ver75)
kde50.sf <- st_as_sf(ver50)
##making the plot
kde.plot <- ggplot() + theme_bw() +
theme(axis.text.y = element_text(angle = 90, hjust = 0.5, vjust = 0.5)) +
geom_spatial_rgb(data = emerald.hill, aes(x=x, y=y, r=red, g=green, b=blue)) +
geom_point(data=kde.points, aes(x=x, y=y), color = "lightgray") +
geom_sf(data=kde95.sf, fill = "blue", alpha = 0.4) +
geom_sf(data=kde75.sf, fill = "green", alpha = 0.3) +
geom_sf(data=kde50.sf, fill = "yellow", alpha = 0.2) +
labs(x="Easting (m)", y="Northing (m)", title=kde.points$identifier) +
theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5), panel.grid = element_blank()) +
scale_y_continuous(n.breaks = 4)
kde.plot <- kde.plot + annotate("text", x = 467500, y = 4043640, label = paste("95% ",round(ver95$area,2),"ha"),
fontface = "bold", size = 5, color = "white")
kde.only.plot <- ggplot() + theme_bw() +
theme(axis.text.y = element_text(angle = 90, hjust = 0.5, vjust = 0.5)) +
geom_spatial_rgb(data = emerald.hill, aes(x=x, y=y, r=red, g=green, b=blue)) +
geom_sf(data=kde95.sf, fill = "blue", alpha = 0.4) +
geom_sf(data=kde75.sf, fill = "green", alpha = 0.3) +
geom_sf(data=kde50.sf, fill = "yellow", alpha = 0.2) +
labs(x="Easting (m)", y="Northing (m)", title=kde.points$identifier) +
theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5), panel.grid = element_blank()) +
scale_y_continuous(n.breaks = 4)
kde.only.plot <- kde.only.plot + annotate("text", x = 467500, y = 4043640, label = paste("95%",round(ver95$area,2),"ha"),
fontface = "bold", size = 5, color = "white")
kde.plot + kde.only.plot
Using a 95% KDE, Nuggets range shrinks by half from 9.85 ha to 4.36
ha.
Now let’s compare the minimum convex polygon to the kernel-density
estimation to get a feel of where Nugget likes to hang out at Emerald
Hill.
As seen from the map, Nugget prefers to spend time in the woods in the
eastern portion of Emerald Hill. It is interesting to note that Nugget
spends 50% of their time on an area less than 1 ha. Going forward, it
would be interesting to see how the ranges of other sparrows on Emerald
Hill overlap with Nugget.
Now I will look at how the home range estimation changes when I account for the time between data points.
# read in original dataset and filter to individual
sparrow2 <- read.csv("locationsll.csv")
nugget2 <- sparrow2 %>%
filter(individual.local.identifier == "1E2D334C")
# convert to telemetry data
nugget.telem <- as.telemetry(nugget2,
coords = c("x", "y"),
projection = "+proj=utm +zone=16 +datum=WGS84 +units=m +no_defs")
# calculate fit object
nugget.guess <- ctmm.guess(nugget.telem, interactive=FALSE)
# compute akde and get summary information, note this will take time to run code
nugget.ouf <- ctmm.fit(nugget.telem, nugget.guess)
wAKDE.nugget <- akde(nugget.telem, nugget.ouf, weights=TRUE)
The graph shows the weighted autocorrelated kernel density estimate
(wAKDE) which estimates the animal’s space use while accounting for
location error and temporal autocorrelation. Nugget’s wAKDE is very flat
indicating mostly regular fixes on the GPS. The sudden rise at the right
of the graph indicates a few long gaps occurred where the GPS lost
signal. This is probably due to Nugget leaving Emerald Hill in the
evening to go sleep in another location.
# for home range estimate CI
summary(wAKDE.nugget)
## $DOF
## area bandwidth
## 2259.809 20480.890
##
## $CI
## low est high
## area (hectares) 4.545649 4.739046 4.936415
##
## attr(,"class")
## [1] "area"
# clean simple version
wAKDE1 <- plot(wAKDE.nugget)
From this graph, we can see that the confidence interval for the 95%
range is close together. This is likely due to the high number of data
points we have for Nugget.
# convert to SPDF to convert to sf object for plotting in ggplot
ud.sp <- SpatialPolygonsDataFrame.UD(wAKDE.nugget)
ud.sf <- st_as_sf(ud.sp)
nugget.sf <- st_as_sf(nugget_df, coords = c("utm_easting","utm_northing")) %>% st_set_crs(32647)
# adke summary data
akde.summary <- summary(wAKDE.nugget)
akde.summary[["CI"]][3]
## [1] 4.936415
The 95% KDE from before estimated the home range at 9.36 ha which is slightly smaller but very similar to the ctmm 95% home range estimation. Let’s see how the ctmm home range fits on Emerald Hill.
Lastly, let’s compare all the home range estimates used in this exercise.